home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / command1.c < prev    next >
C/C++ Source or Header  |  1994-11-13  |  14KB  |  559 lines

  1. /*
  2.  * COMMAND1.C:
  3.  *
  4.  *    Command handling/parsing routines.
  5.  *
  6.  *    Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  7.  *
  8.  */
  9.  
  10. #include "mstruct.h"
  11. #include "mextern.h"
  12. #include <ctype.h>
  13. #include <sys/time.h>
  14. #include <string.h>
  15.  
  16. /**********************************************************************/
  17. /*                login                      */
  18. /**********************************************************************/
  19.  
  20. /* This function is the first function that gets input from a player when */
  21. /* he logs in.  It asks for the player's name and password, and performs  */
  22. /* the according function calls.                      */
  23.  
  24. void login(fd, param, str)
  25. int     fd;
  26. int    param;
  27. char    *str;
  28. {
  29.     int        i;
  30.     extern int    Numplayers;
  31.     char        tempstr[20], str2[50];
  32.     long         t;
  33.     creature    *ply_ptr;
  34.  
  35.     switch(param) {
  36.     case 0:
  37.         if(strcmp(Ply[fd].extr->tempstr[0], str)) {
  38.             disconnect(fd);
  39.             return;
  40.         }
  41.         print(fd, "\nPlease enter name: ");
  42.         RETURN(fd, login, 1);
  43.     case 1:
  44.         if(!isalpha(str[0])) {
  45.             print(fd, "Please enter name: ");
  46.             RETURN(fd, login, 1);
  47.         }
  48.  
  49.         if(strlen(str) < 3) {
  50.             print(fd, "Name must be at least 3 characters.\n\n");
  51.             print(fd, "Please enter name: ");
  52.             RETURN(fd, login, 1);
  53.         }
  54.         if(strlen(str) >= 20) {
  55.             print(fd, "Name must be less than characters.\n\n");
  56.             print(fd, "Please enter name: ");
  57.             RETURN(fd, login, 1);
  58.         }
  59.  
  60.         for(i=0; i<strlen(str); i++)
  61.             if(!isalpha(str[i])) {
  62.                 print(fd, "Name must be alphabetic.\n\n");
  63.                 print(fd, "Please enter name: ");
  64.                 RETURN(fd, login, 1);
  65.             }
  66.  
  67.         lowercize(str, 1);
  68.         str[25]=0;
  69.         if(load_ply(str, &ply_ptr) < 0) {
  70.             strcpy(Ply[fd].extr->tempstr[0], str);
  71.             print(fd, "\n%s? Did I get that right? ", str);
  72.             RETURN(fd, login, 2);
  73.         }
  74.  
  75.         else {
  76.             ply_ptr->fd = -1;
  77.             Ply[fd].ply = ply_ptr;
  78. #ifdef CHECKDOUBLE
  79.             if(checkdouble(ply_ptr->name)) {
  80.                 write(fd, "No simultaneous playing.\n\r", 26);
  81.                 disconnect(fd);
  82.                 return;
  83.             }
  84. #endif
  85.             print(fd, "%c%c%cPlease enter password: ", 255, 251, 1);
  86.             RETURN(fd, login, 3);
  87.         }
  88.  
  89.     case 2:
  90.         if(str[0] != 'y' && str[0] != 'Y') {
  91.             Ply[fd].extr->tempstr[0][0] = 0;
  92.             print(fd, "Please enter name: ");
  93.             RETURN(fd, login, 1);
  94.         }
  95.         else {
  96.             print(fd, "\nHit return: ");
  97.             RETURN(fd, create_ply, 1);
  98.         }
  99.  
  100.     case 3:
  101.         if(strcmp(str, Ply[fd].ply->password)) {
  102.             write(fd, "\255\252\1\n\rIncorrect.\n\r", 17);
  103.             disconnect(fd);
  104.             return;
  105.         }
  106.         else {
  107.             print(fd, "%c%c%c\n\r", 255, 252, 1);
  108.             strcpy(tempstr, Ply[fd].ply->name);
  109.             for(i=0; i<Tablesize; i++)
  110.                 if(Ply[i].ply && i != fd)
  111.                     if(!strcmp(Ply[i].ply->name, 
  112.                        Ply[fd].ply->name))
  113.                         disconnect(i);    
  114.             free_crt(Ply[fd].ply);
  115.         if(load_ply(tempstr, &Ply[fd].ply) < 0)
  116.         {
  117.             write(fd, "Player nolonger exits!\n\r", 24);
  118.                         t = time(0);
  119.                         strcpy(str2, (char *)ctime(&t));
  120.                         str2[strlen(str2)-1] = 0;
  121.                         logn("sui_crash","%s: %s (%s) suicided.\n", 
  122.                 str2, Ply[fd].ply->name, Ply[fd].io->address);         
  123.             disconnect(fd);
  124.             return;
  125.         }
  126.             Ply[fd].ply->fd = fd;
  127.             init_ply(Ply[fd].ply);
  128.             RETURN(fd, command, 1);
  129.         }
  130.     }
  131. }
  132.  
  133. /**********************************************************************/
  134. /*                create_ply                  */
  135. /**********************************************************************/
  136.  
  137. /* This function allows a new player to create his or her character. */
  138.  
  139. void create_ply(fd, param, str)
  140. int    fd;
  141. int    param;
  142. char    *str;
  143. {
  144.     int     i, k, l, n, sum;
  145.     int    num[5];
  146.  
  147.     switch(param) {
  148.     case 1:
  149.         print(fd,"\n\n");
  150.         Ply[fd].ply = (creature *)malloc(sizeof(creature));
  151.         if(!Ply[fd].ply)
  152.             merror("create_ply", FATAL);
  153.         zero(Ply[fd].ply, sizeof(creature));
  154.         Ply[fd].ply->fd = -1;
  155.         Ply[fd].ply->rom_num = 1;
  156.         print(fd, "Male or Female: ");
  157.         RETURN(fd, create_ply, 2);
  158.     case 2:
  159.         if(low(str[0]) != 'm' && low(str[0]) != 'f') {
  160.             print(fd, "Male or Female: ");
  161.             RETURN(fd, create_ply, 2);
  162.         }
  163.         if(low(str[0]) == 'm')
  164.             F_SET(Ply[fd].ply, PMALES);
  165.         print(fd, "\nAvailable classes:\n");
  166.         print(fd, "Assassin, Barbarian, Cleric, Fighter,\n");
  167.         print(fd, "Mage, Paladin, Ranger, Thief\n");
  168.         print(fd, "Choose one: ");
  169.         RETURN(fd, create_ply, 3);
  170.     case 3:
  171.         switch(low(str[0])) {
  172.             case 'a': Ply[fd].ply->class = ASSASSIN; break;
  173.             case 'b': Ply[fd].ply->class = BARBARIAN; break;
  174.             case 'c': Ply[fd].ply->class = CLERIC; break;
  175.             case 'f': Ply[fd].ply->class = FIGHTER; break;
  176.             case 'm': Ply[fd].ply->class = MAGE; break;
  177.             case 'p': Ply[fd].ply->class = PALADIN; break;
  178.             case 'r': Ply[fd].ply->class = RANGER; break;
  179.             case 't': Ply[fd].ply->class = THIEF; break;
  180.             default: print(fd, "Choose one: "); 
  181.                  RETURN(fd, create_ply, 3);
  182.         }
  183.         print(fd, "\nYou have 54 points to distribute among your 5 stats. Please enter your 5\nnumbers in the following order: Strength, Dexterity, Constitution,\nIntelligence, Piety.  No stat may be smaller than 3 or larger than 18.\nUse the following format: 
  184. ## ## ## ## ##\n");
  185.         print(fd, ": ");
  186.         RETURN(fd, create_ply, 4);
  187.     case 4:
  188.         n = strlen(str); l = 0; k = 0;
  189.         for(i=0; i<=n; i++) {
  190.             if(str[i]==' ' || str[i]==0) {
  191.                 str[i] = 0;
  192.                 num[k++] = atoi(&str[l]);
  193.                 l = i+1;
  194.             }
  195.             if(k>4) break;
  196.         }
  197.         if(k<5) {
  198.             print(fd, "Please enter all 5 numbers.\n");
  199.             print(fd, ": ");
  200.             RETURN(fd, create_ply, 4);
  201.         }
  202.         sum = 0;
  203.         for(i=0; i<5; i++) {
  204.             if(num[i] < 3 || num[i] > 18) {
  205.                 print(fd, "No stats < 3 or > 18 please.\n");
  206.                 print(fd, ": ");
  207.                 RETURN(fd, create_ply, 4);
  208.             }
  209.             sum += num[i];
  210.         }
  211.         if(sum > 54) {
  212.             print(fd, "Stat total may not exceed 54.\n");
  213.             print(fd, ": ");
  214.             RETURN(fd, create_ply, 4);
  215.         }
  216.         Ply[fd].ply->strength = num[0];
  217.         Ply[fd].ply->dexterity = num[1];
  218.         Ply[fd].ply->constitution = num[2];
  219.         Ply[fd].ply->intelligence = num[3];
  220.         Ply[fd].ply->piety = num[4];
  221.         print(fd, "\nChoose a weapons proficiency:\n");
  222.         print(fd, "Sharp, Thrusting, Blunt, Pole, Missile.\n");
  223.         print(fd, ": ");
  224.         RETURN(fd, create_ply, 5);
  225.     case 5:
  226.         switch(low(str[0])) {
  227.             case 's': Ply[fd].ply->proficiency[0]=1024; break;
  228.             case 't': Ply[fd].ply->proficiency[1]=1024; break;
  229.             case 'b': Ply[fd].ply->proficiency[2]=1024; break;
  230.             case 'p': Ply[fd].ply->proficiency[3]=1024; break;
  231.             case 'm': Ply[fd].ply->proficiency[4]=1024; break;
  232.             default: print(fd, "Try again.\n: ");
  233.                  RETURN(fd, create_ply, 5);
  234.         }
  235.         print(fd, "\nLawful players cannot attack or steal from other players, nor can they\nbe attacked or stolen from by other players.");
  236.         print(fd, "\nChaotic players may attack or steal from other chaotic players, and they can\nbe attacked or stolen from by other chaotic players.\n");
  237.         print(fd, "\nChoose an alignment, Chaotic or Lawful: ");
  238.         RETURN(fd, create_ply, 6);
  239.     case 6:
  240.         if(low(str[0]) == 'c')
  241.             F_SET(Ply[fd].ply, PCHAOS);
  242.         else if(low(str[0]) == 'l')
  243.             F_CLR(Ply[fd].ply, PCHAOS);
  244.         else {
  245.             print(fd, "Chaotic or Lawful: ");
  246.             RETURN(fd, create_ply, 6);
  247.         }
  248.         print(fd, "\nAvailable races:");
  249.         print(fd, "\nDwarf, Elf, Gnome, Half-elf,");
  250.         print(fd, "\nHalf-giant, Hobbit, Human, Orc");
  251.         print(fd, "\nChoose one: ");
  252.         RETURN(fd, create_ply, 7);
  253.     case 7:
  254.         switch(low(str[0])) {
  255.         case 'd': Ply[fd].ply->race = DWARF; break;
  256.         case 'e': Ply[fd].ply->race = ELF; break;
  257.         case 'g': Ply[fd].ply->race = GNOME; break;
  258.         case 'o': Ply[fd].ply->race = ORC; break;
  259.         case 'h': switch(low(str[1])) {
  260.             case 'a': switch(low(str[5])) {
  261.                 case 'e': Ply[fd].ply->race = HALFELF; break;
  262.                 case 'g': Ply[fd].ply->race = HALFGIANT; break;
  263.                 }
  264.                 break;
  265.             case 'o': Ply[fd].ply->race = HOBBIT; break;
  266.             case 'u': Ply[fd].ply->race = HUMAN; break;
  267.             }
  268.             break;
  269.         }
  270.         if(!Ply[fd].ply->race) {
  271.             print(fd, "\nChoose one: ");
  272.             RETURN(fd, create_ply, 7);
  273.         }
  274.  
  275.         switch(Ply[fd].ply->race) {
  276.         case DWARF: 
  277.             Ply[fd].ply->strength++; 
  278.             Ply[fd].ply->piety--; 
  279.             break;
  280.         case ELF: 
  281.             Ply[fd].ply->intelligence+=2;
  282.             Ply[fd].ply->constitution--;
  283.             Ply[fd].ply->strength--; 
  284.             break;
  285.         case GNOME:
  286.             Ply[fd].ply->piety++;
  287.             Ply[fd].ply->strength--;
  288.             break;
  289.         case HALFELF: 
  290.             Ply[fd].ply->intelligence++; 
  291.             Ply[fd].ply->constitution--; 
  292.             break;
  293.         case HOBBIT: 
  294.             Ply[fd].ply->dexterity++; 
  295.             Ply[fd].ply->strength--; 
  296.             break;
  297.         case HUMAN: 
  298.             Ply[fd].ply->constitution++; 
  299.             break;
  300.         case ORC: 
  301.             Ply[fd].ply->strength++; 
  302.             Ply[fd].ply->constitution++;
  303.             Ply[fd].ply->dexterity--; 
  304.             Ply[fd].ply->intelligence--;
  305.             break;
  306.         case HALFGIANT: 
  307.             Ply[fd].ply->strength+=2; 
  308.             Ply[fd].ply->intelligence--; 
  309.             Ply[fd].ply->piety--; 
  310.             break;
  311.         }
  312.  
  313.         print(fd, "\nChoose a password (up to 14 chars): ");
  314.         RETURN(fd, create_ply, 8);
  315.     case 8:
  316.         if(strlen(str) > 14) {
  317.             print(fd, "Too long.\nChoose a password: ");
  318.             RETURN(fd, create_ply, 8);
  319.         }
  320.         if(strlen(str) < 3) {
  321.             print(fd, "Too short.\nChoose a password: ");
  322.             RETURN(fd, create_ply, 8);
  323.         }
  324.         strncpy(Ply[fd].ply->password, str, 14);
  325.         strcpy(Ply[fd].ply->name, Ply[fd].extr->tempstr[0]);
  326.         up_level(Ply[fd].ply);
  327.         Ply[fd].ply->fd = fd;
  328.         init_ply(Ply[fd].ply);
  329.         save_ply(Ply[fd].ply->name, Ply[fd].ply);
  330.         print(fd, "\n");
  331.  
  332.         print(fd, "Type 'welcome' at prompt to get more info on the game\nand help you get started.\n");
  333.  
  334.         RETURN(fd, command, 1);
  335.     }
  336. }
  337.  
  338. /**********************************************************************/
  339. /*                command                       */
  340. /**********************************************************************/
  341.  
  342. /* This function handles the main prompt commands, and calls the       */
  343. /* appropriate function, depending on what service is requested by the     */
  344. /* player.                                */
  345.  
  346. void command(fd, param, str)
  347. int    fd;
  348. int    param;
  349. char    *str;
  350. {
  351.     cmd    cmnd;
  352.     int    n;
  353.     unsigned char ch;
  354.  
  355. #ifdef RECORD_ALL
  356. /*
  357. this logn commands wil print out all the commands entered by players.
  358. It should be used in extreme case hen trying to isolate a players
  359. input which causes a crash.
  360. */
  361.  
  362. logn("all_cmd","\n%s-%d (%d): %s\n",Ply[fd].ply->name,fd,Ply[fd].ply->rom_num,str);  
  363. #endif RECORD_ALL
  364.  
  365.     switch(param) {
  366.     case 1:
  367.  
  368.         if(F_ISSET(Ply[fd].ply, PHEXLN)) {
  369.             for(n=0;n<strlen(str);n++) {
  370.                 ch = str[n];
  371.                 print(fd, "%02X", ch);
  372.             }
  373.             print(fd, "\n");
  374.         }
  375.  
  376.         if(!strcmp(str, "!"))
  377.             strncpy(str, Ply[fd].extr->lastcommand, 79);
  378.  
  379.         if(str[0]) {
  380.             for(n=0; str[n] && str[n] == ' '; n++) ;
  381.             strncpy(Ply[fd].extr->lastcommand, &str[n], 79);
  382.         }
  383.  
  384.         strncpy(cmnd.fullstr, str, 255);
  385.         lowercize(str, 0);
  386.         parse(str, &cmnd); n = 0;
  387.  
  388.         if(cmnd.num)
  389.             n = process_cmd(fd, &cmnd);
  390.         else
  391.             n = PROMPT;
  392.  
  393.         if(n == DISCONNECT) {
  394.             write(fd, "Goodbye!\n\r\n\r", 11);
  395.             disconnect(fd);
  396.             return;
  397.         }
  398.         else if(n == PROMPT) {
  399.             if(F_ISSET(Ply[fd].ply, PPROMP))
  400.                 sprintf(str, "(%d H %d M): ", 
  401.                     Ply[fd].ply->hpcur, Ply[fd].ply->mpcur);
  402.             else
  403.                 strcpy(str, ": ");
  404.             write(fd, str, strlen(str));
  405.             if(Spy[fd] > -1) write(Spy[fd], str, strlen(str));
  406.         }
  407.  
  408.         if(n != DOPROMPT) {
  409.             RETURN(fd, command, 1);
  410.         }
  411.         else
  412.             return;
  413.     }
  414. }
  415.  
  416. /**********************************************************************/
  417. /*                parse                      */
  418. /**********************************************************************/
  419.  
  420. /* This function takes the string in the first parameter and breaks it */
  421. /* up into its component words, stripping out useless words.  The      */
  422. /* resulting words are stored in a command structure pointed to by the */
  423. /* second argument.                                */
  424.  
  425. void parse(str, cmnd)
  426. char    *str;
  427. cmd    *cmnd;
  428. {
  429.     int    i, j, l, m, n, o, art;
  430.     char    tempstr[25];
  431.  
  432.     l = m = n = 0;
  433.     j = strlen(str);
  434.  
  435.     for(i=0; i<=j; i++) {
  436.         if(str[i] == ' ' || str[i] == '#' || str[i] == 0) {
  437.             str[i] = 0;    /* tokenize */
  438.  
  439.             /* Strip extra white-space */
  440.             while((str[i+1] == ' ' || str[i] == '#') && i < j+1)
  441.                 str[++i] = 0;
  442.  
  443.             strncpy(tempstr, &str[l], 24); tempstr[24] = 0;
  444.             l = i+1;
  445.             if(!strlen(tempstr)) continue;
  446.  
  447.             /* Ignore article/useless words */
  448.             o = art = 0;
  449.             while(article[o][0] != '@') {
  450.                 if(!strcmp(article[o++], tempstr)) {
  451.                     art = 1;
  452.                     break;
  453.                 }
  454.             }
  455.             if(art) continue;
  456.  
  457.             /* Copy into command structure */
  458.             if(n == m) {
  459.                 strncpy(cmnd->str[n++], tempstr, 20);
  460.                 cmnd->val[m] = 1L;
  461.             }
  462.             else if(isdigit(tempstr[0]) || (tempstr[0] == '-' &&
  463.                 isdigit(tempstr[1]))) {
  464.                 cmnd->val[m++] = atol(tempstr);
  465.             }
  466.             else {
  467.                 strncpy(cmnd->str[n++], tempstr, 20);
  468.                 cmnd->val[m++] = 1L;
  469.             }
  470.  
  471.         }
  472.         if(m >= COMMANDMAX) {
  473.             n = 5;
  474.             break;
  475.         }
  476.     }
  477.  
  478.     if(n > m)
  479.         cmnd->val[m++] = 1L;
  480.     cmnd->num = n;
  481.  
  482. }
  483.  
  484. /**********************************************************************/
  485. /*                process_cmd                  */
  486. /**********************************************************************/
  487.  
  488. /* This function takes the command structure of the person at the socket */
  489. /* in the first parameter and interprets the person's command.         */
  490.  
  491. int process_cmd(fd, cmnd)
  492. int    fd;
  493. cmd    *cmnd;
  494. {
  495.     int    match=0, cmdno=0, c=0, n;
  496.  
  497.     do {
  498.         if(!strcmp(cmnd->str[0], cmdlist[c].cmdstr)) {
  499.             match = 1;
  500.             cmdno = c;
  501.             break;
  502.         }
  503.         else if(!strncmp(cmnd->str[0], cmdlist[c].cmdstr, 
  504.             strlen(cmnd->str[0]))) {
  505.             match++;
  506.             cmdno = c;
  507.         }
  508.         c++;
  509.     } while(cmdlist[c].cmdno);
  510.  
  511.     if(match == 0) {
  512.         print(fd, "The command \"%s\" does not exist.\n",
  513.               cmnd->str[0]);
  514.         RETURN(fd, command, 1);
  515.     }
  516.  
  517.     else if(match > 1) {
  518.         print(fd, "Command is not unique.\n");
  519.         RETURN(fd, command, 1);
  520.     }
  521.  
  522.     if(cmdlist[cmdno].cmdno < 0)
  523.         return(special_cmd(Ply[fd].ply, 0-cmdlist[cmdno].cmdno, cmnd));
  524.     
  525.     return((*cmdlist[cmdno].cmdfn)(Ply[fd].ply, cmnd));
  526.  
  527. }
  528.  
  529. #ifdef CHECKDOUBLE
  530.  
  531. int checkdouble(name)
  532. char *name;
  533. {
  534.     char    path[128], tempname[80];
  535.     FILE     *fp;
  536.     int    rtn=0;
  537.  
  538.     sprintf(path, "%s/simul/%s", PLAYERPATH, name);
  539.     fp = fopen(path, "r");
  540.     if(!fp)
  541.         return(0);
  542.  
  543.     while(!feof(fp)) {
  544.         fgets(tempname, 80, fp);
  545.         tempname[strlen(tempname)-1] = 0;
  546.         if(!strcmp(tempname, name))
  547.             continue;
  548.         if(find_who(tempname)) {
  549.             rtn = 1;
  550.             break;
  551.         }
  552.     }
  553.  
  554.     fclose(fp);
  555.     return(rtn);
  556. }
  557.  
  558. #endif
  559.